package com.xnyzc.lhy.finance.utils;

import com.xnyzc.lhy.common.exception.InvoiceException;
import com.xnyzc.lhy.common.penum.invoice.EInvoiceErrorCode;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.finance.entity.invoice.*;
import com.xnyzc.lhy.finance.entity.params.invoice.InvoiceApplyForDiDiParam;
import com.xnyzc.lhy.finance.entity.params.invoice.InvoiceInvalidDiDiParam;
import com.xnyzc.lhy.finance.entity.params.invoice.InvoiceQueryDiDiParam;
import com.xnyzc.lhy.finance.service.invoice.IOaSysInvoiceStrategyService;
import com.xnyzc.lhy.resource.entity.invoice.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Data
@Service
@Slf4j
public class InvoiceUtils {
    @Value("${global.invoice.org.taxTitle}")
    private String taxTitle;

    @Value("${global.invoice.org.terminalCode}")
    private String terminalCode;

    @Value("${global.invoice.org.taxNo}")
    private String taxNo;

    @Autowired
    IOaSysInvoiceStrategyService iOaSysInvoiceStrategyService;

    /**
     * 获取默认开票策略
     * @return 开票策略
     */
    public InvoiceStrategy getDefaultStrategy()
    {
        InvoiceStrategy invoiceStrategy = new InvoiceStrategy();

        /**
         * 开票机构
         */
        InvoiceOrg invoiceOrg = new InvoiceOrg();
        //单位税号
        invoiceOrg.setOrgTaxNo(this.getTaxNo());

        //开票点编码
        invoiceOrg.setInvoiceTerminalCode(this.getTerminalCode());

        //机构名称
        invoiceOrg.setTaxTitle(this.getTaxTitle());

        invoiceStrategy.setInvoiceOrg(invoiceOrg);

        //设置开票策略
        setInvoiceStrategy(invoiceStrategy);

        return invoiceStrategy;
    }

    /**
     * 从数据库配置中获取开票策略
     * @param invoiceStrategy
     */
    private void setInvoiceStrategy(InvoiceStrategy invoiceStrategy)
    {
        try {
            OaSysInvoiceStrategy oaSysInvoiceStrategy = iOaSysInvoiceStrategyService.selectDefaultOaSysInvoiceStrategy();

            if(oaSysInvoiceStrategy != null)
            {
                /**
                 * 特殊票种标记
                 */
                invoiceStrategy.setInvoiceSpecialMark(oaSysInvoiceStrategy.getInvoiceSpecialMark());

                /**
                 * 征税方式
                 */
                invoiceStrategy.setTaxationMode(oaSysInvoiceStrategy.getTaxationMode());

                /**
                 * 发票种类编码
                 */
                invoiceStrategy.setInvoiceTypeCode(oaSysInvoiceStrategy.getInvoiceTypeCode());

                /**
                 * 开票人
                 */
                invoiceStrategy.setDrawer(oaSysInvoiceStrategy.getDrawer());

                /**
                 * 开票类型
                 */
                invoiceStrategy.setInvoiceType(oaSysInvoiceStrategy.getInvoiceType());

                /**
                 * 商品编码
                 */
                invoiceStrategy.setGoodsCode(oaSysInvoiceStrategy.getGoodsCode());

                /**
                 * 商品名称
                 */
                invoiceStrategy.setGoodsName(oaSysInvoiceStrategy.getGoodsName());

                /**
                 * 税率
                 */
                invoiceStrategy.setGoodsTaxRate(oaSysInvoiceStrategy.getGoodsTaxRate());

                /**
                 * 含税标志
                 */
                invoiceStrategy.setPriceTaxMark(oaSysInvoiceStrategy.getPriceTaxMark());

                /**
                 * 是否使用优惠政策
                 */
                invoiceStrategy.setPreferentialMark(oaSysInvoiceStrategy.getPreferentialMark());

                /**
                 * 发票行性质
                 */
                invoiceStrategy.setSetGoodsLineNature(oaSysInvoiceStrategy.getSetGoodsLineNature());
            }
            else {
                log.error("获取开发票策略出错");
                throw InvoiceException.create(EInvoiceErrorCode.initInvoiceError);
            }
        } catch (Exception ex){
            log.error("获取开发票策略出错");
            throw InvoiceException.create(EInvoiceErrorCode.initInvoiceError);
        }
    }


    /**
     * 设置发票策略，静态数据
     * 此方法暂时不使用
     * @param invoiceStrategy
     */
    private void setStaticInvoiceStrategy(InvoiceStrategy invoiceStrategy)
    {

        /**
         * 特殊票种标记 00：普通发票
         */
        invoiceStrategy.setInvoiceSpecialMark("00");

        /**
         * 征税方式 0：普通征税，2：差额征税
         */
        invoiceStrategy.setTaxationMode("0");

        /**
         * 发票种类编码 007:增值税普通发票。026增值税电子发票
         */
        invoiceStrategy.setInvoiceTypeCode("026");

        /**
         * 开票人
         */
        invoiceStrategy.setDrawer("张三");

        /**
         * 开票类型 0:正数发票（蓝票）
         */
        invoiceStrategy.setInvoiceType("0");

        /**
         * 商品编码
         */
        invoiceStrategy.setGoodsCode("1090305020100000000");

        /**
         * 商品名称
         */
        invoiceStrategy.setGoodsName("*机动车*机动车");

        /**
         * 税率
         */
        invoiceStrategy.setGoodsTaxRate(0.03);

        /**
         * 含税标志  1：含税
         */
        invoiceStrategy.setPriceTaxMark("1");

        /**
         * 是否使用优惠政策 0:未使用
         */
        invoiceStrategy.setPreferentialMark("0");

        /**
         * 发票行性质 0：正常行
         */
        invoiceStrategy.setSetGoodsLineNature("0");
    }

    /**
     *创建didi请求开票的发票请求数据
     * @param invoiceStrategy 开票策略
     * @param invoiceApplyForDiDiParam 滴滴参数
     * @return 发票请求数据
     */
    public InvoiceParam createDiDiInvoiceParam(InvoiceStrategy invoiceStrategy, InvoiceApplyForDiDiParam invoiceApplyForDiDiParam){

        //开发票申请部分信息
        InvoiceApplyParam invoiceApplyParam  = new InvoiceApplyParam();
        //开票流水号=DiDi发票唯一发票编号
        invoiceApplyParam.setSerialNo(invoiceApplyForDiDiParam.getInvoiceId());
        //征税方式=0普通增税
        invoiceApplyParam.setTaxationMode(invoiceStrategy.getTaxationMode());

        //开发票发票部分信息
        InvoiceInfoParam invoiceInfoParam = new InvoiceInfoParam();
        //发票种类编码=026增值税电子发票
        invoiceInfoParam.setInvoiceTypeCode(invoiceStrategy.getInvoiceTypeCode());
        //特殊票种标记=00：普通发票
        invoiceInfoParam.setInvoiceSpecialMark(invoiceStrategy.getInvoiceSpecialMark());
        //销方单位税号
        invoiceInfoParam.setSellerTaxNo(invoiceStrategy.getInvoiceOrg().getOrgTaxNo());
        //开票点编码
        invoiceInfoParam.setInvoiceTerminalCode(invoiceStrategy.getInvoiceOrg().getInvoiceTerminalCode());
        //购方单位名称
        invoiceInfoParam.setBuyerName(invoiceApplyForDiDiParam.getInvoiceTitle());
        //购方单位税号
        invoiceInfoParam.setBuyerTaxNo(invoiceApplyForDiDiParam.getCustomerIdentifier());
        //开票人
        invoiceInfoParam.setDrawer(invoiceStrategy.getDrawer());
        //开票类型
        invoiceInfoParam.setInvoiceType(invoiceStrategy.getInvoiceType());


        //开发票发票详情信息
        List<InvoiceDetailParam> invoiceDetailListParam = new ArrayList<InvoiceDetailParam>();
        InvoiceDetailParam invoiceDetailParam = new InvoiceDetailParam();
        //明细行号
        invoiceDetailParam.setGoodsLineNo("1");
        //发票行性质=0：正常行
        invoiceDetailParam.setGoodsLineNature(invoiceStrategy.getSetGoodsLineNature());
        //商品编码
        invoiceDetailParam.setGoodsCode(invoiceStrategy.getGoodsCode());
        //商品名称
        invoiceDetailParam.setGoodsName(invoiceStrategy.getGoodsName());
        //金额
        invoiceDetailParam.setGoodsTotalPrice(Double.valueOf(invoiceApplyForDiDiParam.getInvoiceAmount()));
        //税率
        invoiceDetailParam.setGoodsTaxRate(invoiceStrategy.getGoodsTaxRate());
        //税率=1：含税
        invoiceDetailParam.setPriceTaxMark(invoiceStrategy.getPriceTaxMark());
        //是否使用优惠政策=0:未使用
        invoiceDetailParam.setPreferentialMark(invoiceStrategy.getPreferentialMark());

        invoiceDetailListParam.add(invoiceDetailParam);


        //组件开票参数
        InvoiceParam invoiceParam = new InvoiceParam();
        invoiceParam.setInvoiceApplyParam(invoiceApplyParam);
        invoiceParam.setInvoiceInfoParam(invoiceInfoParam);
        invoiceParam.setInvoiceDetailListParam(invoiceDetailListParam);

        return invoiceParam;
    }

    /**
     * 创建发票板式文件生成参数
     * @param oaSysInvoice
     * @return
     */
    public InvoiceFormatFileParam createInvoiceFormatFileParam(OaSysInvoice oaSysInvoice) {
        InvoiceFormatFileParam invoiceFormatFileParam = new InvoiceFormatFileParam();

        /**
         * 纳税人识别号
         */
        invoiceFormatFileParam.setSellerTaxNo(oaSysInvoice.getOaSysInvoiceInfo().getSellerTaxNo());

        /**
         * 开票流水号,流水号和发票号码代码二选一必填
         */
        invoiceFormatFileParam.setSerialNo(oaSysInvoice.getOaSysInvoiceApply().getSerialNo());

        /**
         * 发票代码,流水号和发票号码代码二选一必填
         */
        invoiceFormatFileParam.setInvoiceCode(oaSysInvoice.getOaSysInvoiceInfo().getInvoiceCode());

        /**
         * 发票号码
         */
        invoiceFormatFileParam.setInvoiceNo(oaSysInvoice.getOaSysInvoiceInfo().getInvoiceNo());

        /**
         * 推送标志 0：不推送 1：推送（邮箱电话必填一个）
         */
        invoiceFormatFileParam.setPushType("0");

        /**
         * 购方客户邮箱
         */
        invoiceFormatFileParam.setBuyerEmail(oaSysInvoice.getOaSysInvoiceApply().getUserEmail());

        /**
         * 购方客户电话
         */
        invoiceFormatFileParam.setBuyerPhone(oaSysInvoice.getOaSysInvoiceApply().getUserTelphone());

        return invoiceFormatFileParam;
    }

    /**
     * 创建发票作废参数
     * @param oaSysInvoiceInfo
     * @param invoiceInvalidDiDiParam
     * @return
     */
    public InvoiceInvalidParam createInvoiceInvalidDiDiParam(OaSysInvoiceApply oaSysInvoiceApply,OaSysInvoiceInfo oaSysInvoiceInfo, InvoiceInvalidDiDiParam invoiceInvalidDiDiParam) {
        InvoiceInvalidParam invoiceInvalidParam = new InvoiceInvalidParam();
        /**
         * 设备类型
         */
        invoiceInvalidParam.setDeviceType(oaSysInvoiceApply.getDeviceType());

        /**
         * 作废类型=1：已开票作废
         */
        invoiceInvalidParam.setInvoiceInvalidType("1");

        /**
         * 纳税人识别号
         */
        invoiceInvalidParam.setSellerTaxNo(oaSysInvoiceInfo.getSellerTaxNo());

        /**
         * 发票种类编码
         */
        invoiceInvalidParam.setInvoiceTypeCode(oaSysInvoiceInfo.getInvoiceTypeCode());

        /**
         * 开票点编码
         */
        invoiceInvalidParam.setInvoiceTerminalCode(oaSysInvoiceInfo.getInvoiceTerminalCode());

        /**
         * 发票编码
         */
        invoiceInvalidParam.setInvoiceCode(oaSysInvoiceInfo.getInvoiceCode());

        /**
         * 发票号码
         */
        invoiceInvalidParam.setInvoiceNo(oaSysInvoiceInfo.getInvoiceNo());

        /**tax_disk_no
         * 税控盘编号
         */
        invoiceInvalidParam.setTaxDiskNo(oaSysInvoiceApply.getTaxDiskNo());

        /**
         * 作废人
         */
        invoiceInvalidParam.setInvoiceInvalidOperator("张三");

        return invoiceInvalidParam;
    }

    /**
     * 创建发票申请信息
     * @param invoiceStrategy
     * @param invoiceApplyForDiDiParam
     * @return
     */
    public OaSysInvoiceApply createOaSysInvoiceApply(InvoiceStrategy invoiceStrategy, InvoiceApplyForDiDiParam invoiceApplyForDiDiParam){

        //开发票申请部分信息
        OaSysInvoiceApply oaSysInvoiceApply = new OaSysInvoiceApply();
        //开票流水号=DiDi发票唯一发票编号
        oaSysInvoiceApply.setSerialNo(invoiceApplyForDiDiParam.getInvoiceId());
        //DiDi发票唯一发票编号
        oaSysInvoiceApply.setDidiInvoiceId(invoiceApplyForDiDiParam.getInvoiceId());
        //征税方式=0普通增税
        oaSysInvoiceApply.setTaxationMode(invoiceStrategy.getTaxationMode());
        //用户手机号
        oaSysInvoiceApply.setUserTelphone(invoiceApplyForDiDiParam.getRegistePhone());
        //用户邮箱地址
        oaSysInvoiceApply.setUserEmail(invoiceApplyForDiDiParam.getEmail());

        return oaSysInvoiceApply;
    }

    /**
     * 创建发票信息
     * @param invoiceStrategy
     * @param invoiceApplyForDiDiParam
     * @return
     */
    public OaSysInvoiceInfo createOaSysInvoiceInfo(InvoiceStrategy invoiceStrategy, InvoiceApplyForDiDiParam invoiceApplyForDiDiParam) {

        //开发票发票部分信息
        OaSysInvoiceInfo oaSysInvoiceInfo = new OaSysInvoiceInfo();
        //发票种类编码=007:增值税普通发票
        oaSysInvoiceInfo.setInvoiceTypeCode(invoiceStrategy.getInvoiceTypeCode());
        //特殊票种标记=00：普通发票
        oaSysInvoiceInfo.setInvoiceSpecialMark(invoiceStrategy.getInvoiceSpecialMark());
        //销方单位税号
        oaSysInvoiceInfo.setSellerTaxNo(invoiceStrategy.getInvoiceOrg().getOrgTaxNo());
        //开票点编码
        oaSysInvoiceInfo.setInvoiceTerminalCode(invoiceStrategy.getInvoiceOrg().getInvoiceTerminalCode());
        //购方单位名称
        oaSysInvoiceInfo.setBuyerName(invoiceApplyForDiDiParam.getInvoiceTitle());
        //购方单位税号
        oaSysInvoiceInfo.setBuyerTaxNo(invoiceApplyForDiDiParam.getCustomerIdentifier());
        //开票人
        oaSysInvoiceInfo.setDrawer(invoiceStrategy.getDrawer());
        //开票类型
        oaSysInvoiceInfo.setInvoiceType(invoiceStrategy.getInvoiceType());

        //开票类别，个人/公司
        oaSysInvoiceInfo.setInvoiceClass(invoiceApplyForDiDiParam.getInvoiceType());

        return oaSysInvoiceInfo;
    }

    /***
     * 发票详情信息
     * @param invoiceStrategy
     * @param invoiceApplyForDiDiParam
     * @return
     */
    public OaSysInvoiceDetail createOaSysInvoiceDetail(InvoiceStrategy invoiceStrategy, InvoiceApplyForDiDiParam invoiceApplyForDiDiParam) {
        //开发票发票详情信息
        OaSysInvoiceDetail oaSysInvoiceDetailList = new OaSysInvoiceDetail();

        //明细行号
        oaSysInvoiceDetailList.setGoodsLineNo("1");
        //发票行性质=0：正常行
        oaSysInvoiceDetailList.setGoodsLineNature(invoiceStrategy.getSetGoodsLineNature());
        //商品编码
        oaSysInvoiceDetailList.setGoodsCode(invoiceStrategy.getGoodsCode());
        //商品名称
        oaSysInvoiceDetailList.setGoodsName(invoiceStrategy.getGoodsName());
        //金额
        oaSysInvoiceDetailList.setGoodsTotalPrice(new BigDecimal(invoiceApplyForDiDiParam.getInvoiceAmount()));
        //税率
        oaSysInvoiceDetailList.setGoodsTaxRate(BigDecimal.valueOf(invoiceStrategy.getGoodsTaxRate()));
        //税率=1：含税
        oaSysInvoiceDetailList.setPriceTaxMark(invoiceStrategy.getPriceTaxMark());
        //是否使用优惠政策=0:未使用
        oaSysInvoiceDetailList.setPreferentialMark(invoiceStrategy.getPreferentialMark());

        return oaSysInvoiceDetailList;
    }

    public Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }
}
